<?php

namespace App\Services;

use App\Common\Libs\Ali\AliYunSms;
use App\Consts\GlobalCacheConst;
use App\Exceptions\Error;
use App\Models\Cache\Cache;
use App\Models\Cache\CacheKey;

/**
 * @package App\Services
 * @see SmsService
 */
class SmsService extends BaseService
{

    /**
     * 发送短信
     * @param $phone
     * @param $templateStr
     * @return bool|mixed
     */
    public function sendSms($phone, $templateStr)
    {
        $code = mt_rand(100000, 999999);
        if ($this->verifySmsAlreadySend($phone, $templateStr)) {
            return Error::handle(lang('Sms has been send'));
        }
        // 发送短信
        $result = AliYunSms::getInstance()->send($phone, $templateStr, $code);
        if (false === $result) {
            return Error::handle(lang('Sms send failed'));
        }
        // 短信模板写入缓存，防止短时间重复发送
        Cache::getInstance([
            'phone'    => $phone,
            'code'     => $code,
            'template' => $templateStr,
        ])->set(CacheKey::SMS_PHONE_TEMPLATE, true, GlobalCacheConst::EXPIRED_SIXTY);
        Cache::getInstance([
            'phone'    => $phone,
            'template' => $templateStr,
        ])->set(CacheKey::SMS_PHONE_ALREADY_SEND, true, GlobalCacheConst::EXPIRED_SIXTY);
        return true;
    }

    /**
     * 校验短信60s内是否发送过
     * @param $phone
     * @param $templateStr
     * @return bool
     */
    public function verifySmsAlreadySend($phone, $templateStr)
    {
        return Cache::getInstance([
            'phone'    => $phone,
            'template' => $templateStr,
        ])->get(CacheKey::SMS_PHONE_ALREADY_SEND);
    }

    /**
     * 校验验证码是否正确
     * @param $code
     * @param $phone
     * @param $template
     * @return bool
     */
    public function checkCodeByPhoneAndTemplate($code, $phone, $template): bool
    {
        // 开发服、测试服可使用特殊验证码
        if ((isDev() && (string)$code === '123456') || (isTest() && (string)$code === '654321')) {
            return true;
        }

        $codeVerify = Cache::getInstance([
            'phone'    => $phone,
            'code'     => $code,
            'template' => $template,
        ])->get(CacheKey::SMS_PHONE_TEMPLATE);
        if (!$codeVerify) {
            return false;
        }

        // 验证后删除此key
        Cache::getInstance([
            'phone'    => $phone,
            'code'     => $code,
            'template' => $template,
        ])->delete(CacheKey::SMS_PHONE_TEMPLATE);

        return true;
    }

}
